/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \brief unpacker for raw data collected by PXI daq
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2021-09-27
  \date 2021-09-27 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date        <th>Author      <th>Description                    </tr>
  <tr>  <td>2021-09-27   <td>Asia Sun    <td>file created                   </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#ifndef ETFPXIUnpacker_h
#define ETFPXIUnpacker_h

#include "ETFUnpacker.h"
#include "online_shm.h"
#include "section_head.h"
#include "fragment_head.h"

class ETFPXISection;
struct fragment_head;

class ETFPXIUnpacker : public ETFUnpacker{
public:
  ETFPXIUnpacker(int id = 0); ///< type=0 is used to indicate PXI daq
  virtual ~ETFPXIUnpacker();

  virtual void Init() override; ///< register the raw data item array
  virtual void Reset() override; ///< clear the output before each event loop

  /// \retval: return index of the event being read
  virtual int GetOneEvent(FILE *file) override; ///< get 1 event to memory from file
  /// \retval: return index of the event being read
  virtual int GetOneEvent(int *fstream) override; ///< get 1 event to memory from stream
  /// write one event to dst - simulate daq to test online applications in ETFAna
  virtual void WriteOneEvent() override;
  virtual bool Unpack() override; ///< complete the unpacking to clones arrays

  virtual bool UnpackGood() const override;
  virtual void PrintSummary() override; ///< print unpacking summary
  virtual ETFPXISection *GetCurrentEvent() const{ return fPXISection; }
  virtual void Print() override; ///< Print the unpacked data of the current event

  void SetIsCheckBunchID(bool opt){ fIsCheckBunchID = opt; }

  static constexpr int kMAX_LEN = online_shm_pxi::MAX_LEN;
  static constexpr int kMAX_SIZE = kMAX_LEN*sizeof(int);
  static constexpr int EDGE_NUM_LIMIT = 30; ///< maximum edge number in a channel

  static const section_head kEmptySectionHead; ///< padding for sim-daq for error events
  static const fragment_head kEmptyFragmentHead; ///< padding for sim-daq for error events

  // ClassDefOverride(ETFPXIUnpacker, 1); // unpacker for PXI raw data

protected:
  virtual void Register() override; ///< register the raw data to the output tree as branches

  ETFPXISection *fPXISection; //! ///< one section is an event
  fragment_head fFrag_h[FRAG_NUM_LIMIT_PER_EVENT]; //!

  int fData[kMAX_LEN]; //! ///< to buffer data of the data zone of a section
  int fChId[CH_NUM_LIMIT_PER_FRAG], fEdgeNum[CH_NUM_LIMIT_PER_FRAG]; //! ///< temporary varibles

  int fBunchIDMisAlignCnt; ///< count for fragments' bunchids' inconsistencies
  bool fIsCheckBunchID; ///< print out section info if a bunchId-misalignment happens

  // note that fOnline[0] is the section_length in words - accroding to Wang's PXI online
  int fOnline[online_shm_pxi::MAX_LEN]; //! ///< store one event - to simulate daq
};

#endif
